import type { CSSProperties } from "vue";
import { computed, defineComponent, nextTick, onMounted, PropType, ref, unref, ImgHTMLAttributes } from "vue";

import Cropper from "cropperjs";
import "cropperjs/dist/cropper.css";
type Options = Cropper.Options;

const defaultOptions: Cropper.Options = {
	// aspectRatio: 16 / 16,
	zoomable: true,
	zoomOnTouch: true,
	zoomOnWheel: true,
	cropBoxMovable: true,
	cropBoxResizable: true,
	toggleDragModeOnDblclick: true,
	autoCrop: true,
	background: true,
	highlight: true,
	center: true,
	responsive: true,
	restore: true,
	checkCrossOrigin: true,
	checkOrientation: true,
	scalable: true,
	modal: true,
	guides: true,
	movable: true,
	rotatable: true
};

const props = {
	src: {
		type: String,
		required: true
	},
	alt: {
		type: String
	},
	width: {
		type: [String, Number],
		default: ""
	},
	height: {
		type: [String, Number],
		default: "360px"
	},
	crossorigin: {
		type: String as PropType<ImgHTMLAttributes["crossorigin"]>,
		default: undefined
	},
	imageStyle: {
		type: Object as PropType<CSSProperties>,
		default() {
			return {};
		}
	},
	options: {
		type: Object as PropType<Options>,
		default() {
			return {};
		}
	}
};

export default defineComponent({
	props,
	setup(props) {
		const cropper: any = ref<Cropper>();
		const imgElRef = ref();

		const isReady = ref<boolean>(false);

		const getImageStyle = computed((): CSSProperties => {
			return {
				height: props.height,
				width: props.width,
				maxWidth: "100%",
				...props.imageStyle
			};
		});

		const getWrapperStyle = computed((): CSSProperties => {
			const { height, width } = props;
			return {
				width: `${width}`.replace(/px/, "") + "px",
				height: `${height}`.replace(/px/, "") + "px"
			};
		});

		function init() {
			const imgEl = unref(imgElRef);
			if (!imgEl) {
				return;
			}
			cropper.value = new Cropper(imgEl, {
				...defaultOptions,
				ready: () => {
					isReady.value = true;
				},
				...props.options
			});
		}

		onMounted(() => {
			nextTick(() => {
				init();
			});
		});

		return {
			props,
			imgElRef,
			cropper,
			getWrapperStyle,
			getImageStyle
		};
	},

	render() {
		return (
			<>
				<div class={{ excludeListeners: true, excludeKeys: ["class"] }} style={this.getWrapperStyle}>
					<img
						ref="imgElRef"
						src={this.props.src}
						alt={this.props.alt}
						crossorigin={this.props.crossorigin}
						style={this.getImageStyle}
					/>
				</div>
			</>
		);
	}
});
